package gdconf

import (
	"server_cluster/common/logger"
)

// 活动配置表

const (
	ActivityTypeSignIn = 1 // 签到活动
	ActivityTypeZp     = 2 // 转盘活动
)

type SignInReward struct {
	RewardDay int32 // 天数
	RewardId  int32 // 奖励id
}

type SignInActivityConfig struct {
	ActivityConfig
	DailyReward          []*SignInReward // 每日奖励列表
	TotalReward          []*SignInReward // 累计奖励列表
	DailyRoutineRewardId int32           // 每日常规奖励id
}

type ZpReward struct {
	ItemId             int32 // 道具id
	ItemCount          int32 // 道具数量
	Weight             int32 // 权重
	Index              int32 // 位置
	Count              int32 // 次数
	RewardExpireMailId int32 // 奖励过期邮件id
}

func (z ZpReward) GetWeight() int32 {
	return z.Weight
}

const (
	ZpTaskRefreshTypeDaily      = 1 // 每日刷新
	ZpTaskRefreshTypeResetState = 2 // 重置任务状态
)

type ZpTask struct {
	ActivityTaskConfig
	RefreshType        int32 // 刷新类型
	RewardId           int32 // 奖励id
	RewardCount        int32 // 奖励数量
	RewardExpireMailId int32 // 奖励过期邮件id
}

type ZpActivityConfig struct {
	ActivityConfig
	ZpRewardList   []*ZpReward // 转盘奖励列表
	ZpBdRewardList []*ZpReward // 转盘保底奖励列表
	OnceCostItem   *Item       // 单抽消耗道具
	ProbRuleId     int32       // 概率公式id
	ZpTaskList     []*ZpTask   // 转盘任务列表
	ZpBigReward    string      // 转盘本期大奖
}

func (z *ZpActivityConfig) GetZpTask(taskId int32) *ZpTask {
	for _, zpTask := range z.ZpTaskList {
		if zpTask.TaskId == taskId {
			return zpTask
		}
	}
	return nil
}

type ActivityConfig struct {
	ActivityId        int32    `csv:"Id" gorm:"primary_key;autoIncrement:false"` // 活动id
	Type              int32    `csv:"Type,omitempty"`                            // 活动类型
	StartTime         *Time    `csv:"Startdate,omitempty"`                       // 开始时间
	EndTime           *Time    `csv:"Enddate,omitempty"`                         // 结束时间
	ActivityParamList IntArray `csv:"PayGoal,omitempty"`                         // 活动参数列表
	NeedPlayerLevel   int32    `csv:"Level,omitempty"`                           // 所需玩家等级
}

func (z *ActivityConfig) IsExpire(now int64) bool {
	if z.StartTime != nil && now < z.StartTime.Unix() {
		return true
	}
	if z.EndTime != nil && now > z.EndTime.Unix() {
		return true
	}
	return false
}

func (a *ActivityConfig) TableName() string {
	return "config_activity"
}

func (g *GameDataConfig) saveActivityConfig() {
	saveTableToDb[ActivityConfig](g.Db, readTable[ActivityConfig](g.CsvPathPrefix+"PayActivity.csv"))
}

func (g *GameDataConfig) loadActivityConfig() {
	g.GameDataMaps.ActivityConfigMap = make(map[int32]*ActivityConfig)
	for _, activityConfig := range loadTableFromDb[ActivityConfig](g.Db) {
		g.GameDataMaps.ActivityConfigMap[activityConfig.ActivityId] = activityConfig
	}
	logger.Info("ActivityConfig Count: %v", len(g.GameDataMaps.ActivityConfigMap))
}

func GetActivityConfig(activityId int32) *ActivityConfig {
	value, exist := CONF.GameDataMaps.ActivityConfigMap[activityId]
	if !exist {
		logger.Error("[ConfigNotFound] ActivityConfig, activityId: %v", activityId)
		return nil
	}
	return value
}

func GetActivityConfigMap() map[int32]*ActivityConfig {
	return CONF.GameDataMaps.ActivityConfigMap
}

func ParseSignInActivityConfig(activityConfig *ActivityConfig) *SignInActivityConfig {
	ret := &SignInActivityConfig{
		ActivityConfig:       *activityConfig,
		DailyReward:          make([]*SignInReward, 0),
		TotalReward:          make([]*SignInReward, 0),
		DailyRoutineRewardId: 0,
	}
	for _, activityParamId := range activityConfig.ActivityParamList {
		activityParamConfigList := GetActivityParamConfigByParamId(activityParamId)
		if len(activityParamConfigList) == 0 {
			continue
		}
		switch activityParamConfigList[0].Type {
		case ActivityParamTypeSignInDailyReward:
			for _, activityParamConfig := range activityParamConfigList {
				ret.DailyReward = append(ret.DailyReward, &SignInReward{
					RewardDay: activityParamConfig.Param1,
					RewardId:  activityParamConfig.Param2,
				})
			}
		case ActivityParamTypeSignInTotalReward:
			for _, activityParamConfig := range activityParamConfigList {
				ret.TotalReward = append(ret.TotalReward, &SignInReward{
					RewardDay: activityParamConfig.Param1,
					RewardId:  activityParamConfig.Param2,
				})
			}
		case ActivityParamTypeSignInDailyRoutineReward:
			ret.DailyRoutineRewardId = activityParamConfigList[0].Param2
		}
	}
	return ret
}

func GetSignInActivityConfig(activityId int32) *SignInActivityConfig {
	activityConfig := GetActivityConfig(activityId)
	if activityConfig == nil {
		return nil
	}
	if activityConfig.Type != ActivityTypeSignIn {
		return nil
	}
	return ParseSignInActivityConfig(activityConfig)
}

func GetSignInActivityConfigMap() map[int32]*SignInActivityConfig {
	m := make(map[int32]*SignInActivityConfig)
	for _, activityConfig := range GetActivityConfigMap() {
		if activityConfig.Type != ActivityTypeSignIn {
			continue
		}
		m[activityConfig.ActivityId] = ParseSignInActivityConfig(activityConfig)
	}
	return m
}

func ParseZpActivityConfig(activityConfig *ActivityConfig) *ZpActivityConfig {
	ret := &ZpActivityConfig{
		ActivityConfig: *activityConfig,
		ZpRewardList:   make([]*ZpReward, 0),
		ZpBdRewardList: make([]*ZpReward, 0),
		OnceCostItem:   &Item{ItemId: 0, ItemCount: 0},
		ProbRuleId:     0,
		ZpTaskList:     make([]*ZpTask, 0),
		ZpBigReward:    "",
	}
	for _, activityParamId := range activityConfig.ActivityParamList {
		activityParamConfigList := GetActivityParamConfigByParamId(activityParamId)
		if len(activityParamConfigList) == 0 {
			continue
		}
		switch activityParamConfigList[0].Type {
		case ActivityParamTypeZpReward:
			for _, activityParamConfig := range activityParamConfigList {
				ret.ZpRewardList = append(ret.ZpRewardList, &ZpReward{
					ItemId:    activityParamConfig.Param1,
					ItemCount: activityParamConfig.Param2,
					Weight:    activityParamConfig.Param3,
					Index:     activityParamConfig.Param4,
				})
			}
		case ActivityParamTypeZpBdReward:
			for _, activityParamConfig := range activityParamConfigList {
				ret.ZpBdRewardList = append(ret.ZpBdRewardList, &ZpReward{
					ItemId:             activityParamConfig.Param2,
					ItemCount:          activityParamConfig.Param3,
					Count:              activityParamConfig.Param1,
					RewardExpireMailId: activityParamConfig.Param4,
				})
			}
		case ActivityParamTypeZpTask:
			for _, activityParamConfig := range activityParamConfigList {
				activityTaskConfig := GetActivityTaskConfig(activityParamConfig.Param2)
				if activityTaskConfig == nil {
					continue
				}
				ret.ZpTaskList = append(ret.ZpTaskList, &ZpTask{
					ActivityTaskConfig: *activityTaskConfig,
					RefreshType:        activityParamConfig.Param1,
					RewardId:           activityParamConfig.Param3,
					RewardCount:        activityParamConfig.Param4,
					RewardExpireMailId: activityParamConfig.Param5,
				})
			}
		case ActivityParamTypeZpProbRuleId:
			ret.ProbRuleId = activityParamConfigList[0].Param1
		case ActivityParamTypeZpOnceCostItem:
			ret.OnceCostItem.ItemId = activityParamConfigList[0].Param1
			ret.OnceCostItem.ItemCount = activityParamConfigList[0].Param2
		case ActivityParamTypeZpBigReward:
			ret.ZpBigReward = activityParamConfigList[0].ComplexParam
		}
	}
	return ret
}

func GetZpActivityConfig(activityId int32) *ZpActivityConfig {
	activityConfig := GetActivityConfig(activityId)
	if activityConfig == nil {
		return nil
	}
	if activityConfig.Type != ActivityTypeZp {
		return nil
	}
	return ParseZpActivityConfig(activityConfig)
}

func GetZpActivityConfigMap() map[int32]*ZpActivityConfig {
	m := make(map[int32]*ZpActivityConfig)
	for _, activityConfig := range GetActivityConfigMap() {
		if activityConfig.Type != ActivityTypeZp {
			continue
		}
		m[activityConfig.ActivityId] = ParseZpActivityConfig(activityConfig)
	}
	return m
}
